#!/usr/bin/env python
# -*- coding: ascii -*-
# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
#
# dietcherrypy_skeleton_template - a cherrypy template/demo application
# Copyright (C) 2010  Chris Clark

import os
import sys
import cgi
import urllib
try:
    import webbrowser
except ImportError:
    webbrowser = None

try:
    # Python 2.6+
    import json
except ImportError:
    try:
        # from http://code.google.com/p/simplejson
        import simplejson as json
    except ImportError:
        json = None

if json is None:
    raise ImportError()
    
    def dump_json(x):
        """dumb not safe!"""
        return repr(x)
else:
    dump_json = json.dumps

#import cherrypy # http://www.cherrypy.org/
## rhubarb tart # http://rhubarbtart.org/
## PySite (not Pysite, note case) 
##      http://www.programmingforums.org/forum/f43-python/t9028-pysite-web-development-framework.html
##      http://www.programmingforums.org/thread9028.html
try:
    raise ImportError()  # force usage of dietcherrypy.py
    import cherrypy
    from cherrypy.lib.static import serve_file
    dietcherrypy = None
except ImportError, info:
    import dietcherrypy as cherrypy
    import dietcherrypy
    serve_file = cherrypy.serve_file

############################
## TODO consider moving this into dietcherry
import inspect


def function_arg_list(object):
    """Simplistic method/function argument lister, returns list of strings. 
    Ignores "self" for object methods.
    """
    function_args = inspect.getargspec(object)[0]
    if inspect.ismethod(object):
        function_args = function_args[1:]  # ignore first argument, we assume it is "self"
    return function_args


def form_gen(function_object=None, post=None, text_message=None, url=None, default_values=None):
    """Generates a simple html form
    default_values should be a dict of param names
    """
    # doesn't use a proper template engine (and it probably should)
    if post is None:
        post = False
    if text_message is None:
        text_message = "Please fill in the form and click the submit button"
    
    simple_template = """
<form action="%s" method="%s">
    %s
<br><br>

%s
    <input type="submit" />
</form>
"""    
    
    the_fields = ''
    for arg in function_arg_list(function_object):
        def_val = ''
        if default_values:
            try:
                if default_values[arg] is not None:
                    def_val = default_values[arg]
            except KeyError:
                pass
            
        the_fields += '    %s: <input type="text" name="%s" value="%s"/><br>\n' % (arg, arg, def_val)
    
    if post:
        form_type = "POST"
    else:
        form_type = "GET"
    the_form = simple_template % (function_object.__name__, form_type, text_message, the_fields)
    return the_form

############################


class Root(object):
    def __init__(self):
        self.picdir = os.path.abspath(os.path.dirname(__file__))
        self.picdir = os.path.join(self.picdir, 'data')
    
    def index(self, cached_filename=None):
        if None in [cached_filename]:  # if None in all kwargs
            __result = 'Need something'
            __result += ', at least cached_filename!<br><br>'  # OPTIONAL
            # from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66062
            this_function_name = sys._getframe().f_code.co_name
            this_function = getattr(self, this_function_name)
            __result += form_gen(function_object=this_function, default_values=locals())
            return __result
        
        cached_filename = os.path.join(self.picdir, cached_filename)
        return cached_filename
        ## FIXME kpg to html with some default options
    index.exposed = True


def main(argv=None):
    if argv is None:
        argv = sys.argv
    
    class DumbOpt(object):
        pass
    opt = DumbOpt()
    if webbrowser is None:
        opt.no_webbrowser = True
    else:
        opt.no_webbrowser = False
    
    if os.getenv('SCRIPT_NAME'):
        # Running under CGI
        opt.no_webbrowser = True
    else:
        # Probably desktop app
        print 'cherrypy.__version__', cherrypy.__version__
    
    server_port = 8080
    socket_host = '0.0.0.0'  # allow access from any client
    socket_host = '127.0.0.1'  # only allow access from local machine
    #socket_host = 'localhost'  # only allow access from local machine - NOTE does not seem to work with CherryPy (use 127.0.0.1 instead )
    #socket_host = ''  # same as localhost (with dietcherry and CherryPy 2.x)
    
    if dietcherrypy:
        fname = 'favicon.ico'
        if os.path.exists(fname):
            f = open(fname, 'rb')
            favicon_ico = f.read()
            f.close()
            dietcherrypy.setup_favicon(favicon_ico)
        else:
            dietcherrypy.FAVICON_STR = None
    
    """
    ## cherrypy v3 quickstart (no call backs allowed, need to thread locally)
    #cherrypy.quickstart(Root(form, self._webform_callback))
    
    ### cherrypy 3.0.2 does NOT have server.start_with_callback it is engine..?
    cherrypy.config.update({'server.socketPort':server_port})
    cherrypy.engine.start_with_callback(webbrowser.open, ('http://localhost:%d'%server_port,))
    """
    ### cherrypy 2.?.? (and dietcherrypy)
    #cherrypy.config.update({'server.socketPort': server_port}) # maybe a 3.0 thing?
    cherrypy.config.update({'server.socket_port': server_port, 'server.socket_host': socket_host})  # CherryPy 3.1.2
    mywebapp = Root()
    if opt.no_webbrowser:
        cherrypy.quickstart(mywebapp)
    else:
        # style start for:
        #   CherryPy 3.1 (tested with 3.1.2)
        #   dietcherrypy
        
        def launch_webbrowser():
            url = 'http://localhost:%d' % server_port
            webbrowser.open(url)
        cherrypy.engine.subscribe('start', launch_webbrowser)  # CherryPy 3.1 api
        cherrypy.quickstart(mywebapp)

    return 0


if __name__ == "__main__":
    sys.exit(main())
